import { injectable } from 'inversify'
import passport from 'passport'
import jsonwebtoken from 'jsonwebtoken'
import {Strategy, ExtractJwt} from 'passport-jwt'

@injectable()
export class JWT {
    
    // 定义一个私钥
    private secret = 'f3h4hhiuhuiu%^$%$^%&^sdaf'

    // options
    private jwtOptions = {
        jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),  // jwt来源
        secretOrKey: this.secret
        
    }

    constructor() {
        this.strategy()  // 这里调用一下，注册完成
    }

    public strategy() {
        let stra =  new Strategy(this.jwtOptions, (payload: any, done: Function) => {   // 这里传一个options配置
            // 还有一个参数就是这个回调
            done(null, payload)    // 传载荷
        })  
        // 还需要passport使用注册一下, 插件才会被激活(Strategy是passport-jwt这个插件中的)
        passport.use(stra)
    }

    // 还需要一个中间件   使用静态方法
    static middleware() {  
        // 要经过这个中间件，验证jwt, 灵活用在需要的接口上
        return passport.authenticate('jwt', {session: false})
    }

    /**
     * 生成Token
     */
    public createToken(data:Object) {
        // 生成token, sign 方法的参数，第一个是载荷(就是参数), 第二个参数是一个私钥,第三个参数是配置(可以设置过期时间)
        return jsonwebtoken.sign(data, this.secret, {expiresIn: '7d'})  // 7d表示 7天
    }

    /**
     * jwt关联到 express上，实现这个方法
     */
    public init() {
        return passport.initialize()  // 初始化的方法，中间件中使用一下
    }
}